/**
 * 产品管理控制器 - 处理金融服务产品的创建、查询、管理等REST API接口
 *
 * 开发人员：马勇俐
 * 开发时间：2025-11-16 至 2025-11-20
 * 模块职责：提供金融服务产品相关的REST API接口，支持产品创建、查询、更新、删除等完整产品管理功能
 *
 * 技术要点：
 * - RESTful API设计，遵循REST规范
 * - 多租户架构，企业级数据隔离
 * - AOP审计日志记录操作轨迹
 * - 缓存机制优化产品查询性能
 * - 参数验证和异常处理机制
 *
 * 开发故事：负责产品管理控制器的开发，与产品服务层和前端产品页面深度配合，确保金融产品的完整管理和用户体验。
 */
package com.pbl.controller;

import com.pbl.aspect.AuditLog;
import com.pbl.common.model.ApiResponse;
import com.pbl.entity.Product;
import com.pbl.service.ProductService;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;

@RestController
@RequestMapping("/enterprises/{enterpriseId}/products")
public class ProductController {

    private final ProductService productService;

    /**
     * 构造产品控制器
     * @param productService 产品服务层
     */
    public ProductController(ProductService productService) {
        this.productService = productService;
    }

    /**
     * 获取产品列表
     * 缓存10分钟，按企业ID和状态缓存
     */
    @GetMapping
    @Cacheable(value = "products:list", key = "#enterpriseId + ':' + (#status != null ? #status : 'all')")
    public ApiResponse<List<Product>> list(@PathVariable Long enterpriseId,
                                          @RequestParam(required = false) String status) {
        List<Product> products;
        if ("ACTIVE".equals(status)) {
            products = productService.getActiveProductsByEnterprise(enterpriseId);
        } else {
            products = productService.getProductsByEnterprise(enterpriseId);
        }
        return ApiResponse.success(products);
    }

    /**
     * 获取单个产品
     * 缓存30分钟，按产品ID缓存
     */
    @GetMapping("/{id}")
    @Cacheable(value = "products:detail", key = "#id")
    public ApiResponse<Product> get(@PathVariable Long enterpriseId, @PathVariable Long id) {
        return ApiResponse.success(productService.getProductById(id));
    }

    /**
     * 根据编码获取产品
     * 缓存30分钟，按企业ID和编码缓存
     */
    @GetMapping("/code/{code}")
    @Cacheable(value = "products:code", key = "#enterpriseId + ':' + #code")
    public ApiResponse<Product> getByCode(@PathVariable Long enterpriseId, @PathVariable String code) {
        return ApiResponse.success(productService.getProductByCode(enterpriseId, code));
    }

    /**
     * 创建产品
     * 清除相关缓存
     */
    @AuditLog(action = "product.create", resource = "product")
    @PostMapping
    @CacheEvict(value = {"products:list", "products:search"}, allEntries = true)
    public ApiResponse<Product> create(@PathVariable Long enterpriseId,
                                      @Valid @RequestBody CreateProductRequest request) {
        Product product = productService.createProduct(
                enterpriseId,
                request.getCode(),
                request.getName(),
                request.getDescription(),
                request.getCategory(),
                request.getPrice(),
                request.getCurrency()
        );
        return ApiResponse.success(product);
    }

    /**
     * 更新产品
     * 清除相关缓存
     */
    @AuditLog(action = "product.update", resource = "product")
    @PutMapping("/{id}")
    @CacheEvict(value = {"products:list", "products:detail", "products:code", "products:search"}, allEntries = true)
    public ApiResponse<Product> update(@PathVariable Long enterpriseId, @PathVariable Long id,
                                       @Valid @RequestBody UpdateProductRequest request) {
        Product product = productService.updateProduct(
                id,
                request.getName(),
                request.getDescription(),
                request.getCategory(),
                request.getPrice(),
                request.getCurrency(),
                request.getStatus(),
                request.getSortOrder()
        );
        return ApiResponse.success(product);
    }

    /**
     * 删除产品
     * 清除相关缓存
     */
    @AuditLog(action = "product.delete", resource = "product")
    @DeleteMapping("/{id}")
    @CacheEvict(value = {"products:list", "products:detail", "products:code", "products:search"}, allEntries = true)
    public ApiResponse<Void> delete(@PathVariable Long enterpriseId, @PathVariable Long id) {
        productService.deleteProduct(id);
        return ApiResponse.success();
    }

    /**
     * 搜索产品
     * 缓存5分钟，按企业ID和关键词缓存
     */
    @GetMapping("/search")
    @Cacheable(value = "products:search", key = "#enterpriseId + ':' + #keyword")
    public ApiResponse<List<Product>> search(@PathVariable Long enterpriseId,
                                            @RequestParam String keyword) {
        return ApiResponse.success(productService.searchProducts(enterpriseId, keyword));
    }

    /**
     * 根据分类获取产品
     * 缓存10分钟，按企业ID和分类缓存
     */
    @GetMapping("/category/{category}")
    @Cacheable(value = "products:category", key = "#enterpriseId + ':' + #category")
    public ApiResponse<List<Product>> getByCategory(@PathVariable Long enterpriseId,
                                                    @PathVariable String category) {
        return ApiResponse.success(productService.getProductsByCategory(enterpriseId, category));
    }

    // DTOs
    public static class CreateProductRequest {
        private String code;
        private String name;
        private String description;
        private String category;
        private java.math.BigDecimal price;
        private String currency = "CNY";

        // Getters and setters
        public String getCode() { return code; }
        public void setCode(String code) { this.code = code; }
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }
        public String getCategory() { return category; }
        public void setCategory(String category) { this.category = category; }
        public java.math.BigDecimal getPrice() { return price; }
        public void setPrice(java.math.BigDecimal price) { this.price = price; }
        public String getCurrency() { return currency; }
        public void setCurrency(String currency) { this.currency = currency; }
    }

    public static class UpdateProductRequest {
        private String name;
        private String description;
        private String category;
        private java.math.BigDecimal price;
        private String currency;
        private Product.ProductStatus status;
        private Integer sortOrder;

        // Getters and setters
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }
        public String getCategory() { return category; }
        public void setCategory(String category) { this.category = category; }
        public java.math.BigDecimal getPrice() { return price; }
        public void setPrice(java.math.BigDecimal price) { this.price = price; }
        public String getCurrency() { return currency; }
        public void setCurrency(String currency) { this.currency = currency; }
        public Product.ProductStatus getStatus() { return status; }
        public void setStatus(Product.ProductStatus status) { this.status = status; }
        public Integer getSortOrder() { return sortOrder; }
        public void setSortOrder(Integer sortOrder) { this.sortOrder = sortOrder; }
    }
}
